home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995 February: Tool Chest / Dev.CD Feb 95 / Dev.CD Feb 95.toast / Tool Chest / Development Tools & Languages / Dylan Related / Mindy-1.1 (sources only) / mindy-1.1 / interp / weak.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-28  |  4.1 KB  |  163 lines  |  [TEXT/ttxt]

  1. /**********************************************************************\
  2. *
  3. *  Copyright (c) 1994  Carnegie Mellon University
  4. *  All rights reserved.
  5. *  
  6. *  Use and copying of this software and preparation of derivative
  7. *  works based on this software are permitted, including commercial
  8. *  use, provided that the following conditions are observed:
  9. *  
  10. *  1. This copyright notice must be retained in full on any copies
  11. *     and on appropriate parts of any derivative works.
  12. *  2. Documentation (paper or online) accompanying any system that
  13. *     incorporates this software, or any part of it, must acknowledge
  14. *     the contribution of the Gwydion Project at Carnegie Mellon
  15. *     University.
  16. *  
  17. *  This software is made available "as is".  Neither the authors nor
  18. *  Carnegie Mellon University make any warranty about the software,
  19. *  its performance, or its conformity to any specification.
  20. *  
  21. *  Bug reports, questions, comments, and suggestions should be sent by
  22. *  E-mail to the Internet address "gwydion-bugs@cs.cmu.edu".
  23. *
  24. ***********************************************************************
  25. *
  26. * $Header: weak.c,v 1.5 94/06/27 16:32:48 wlott Exp $
  27. *
  28. * This file implements weak pointers.
  29. *
  30. \**********************************************************************/
  31.  
  32.  
  33. #include "mindy.h"
  34. #include "gc.h"
  35. #include "obj.h"
  36. #include "bool.h"
  37. #include "list.h"
  38. #include "type.h"
  39. #include "class.h"
  40. #include "def.h"
  41. #include "sym.h"
  42. #include "module.h"
  43. #include "error.h"
  44. #include "thread.h"
  45. #include "func.h"
  46. #include "weak.h"
  47.  
  48.  
  49. obj_t obj_WeakPointerClass = NULL;
  50.  
  51. static struct weak_pointer *WeakPointers = NULL;
  52.  
  53. obj_t make_weak_pointer(obj_t object)
  54. {
  55.     obj_t res = alloc(obj_WeakPointerClass, sizeof(struct weak_pointer));
  56.  
  57.     WEAK(res)->object = object;
  58.     WEAK(res)->broken = FALSE;
  59.     WEAK(res)->next = NULL;
  60.  
  61.     return res;
  62. }
  63.  
  64.  
  65. /* Dylan routines. */
  66.  
  67. obj_t dylan_make_weak_pointer(obj_t class, obj_t object)
  68. {
  69.     if (object == obj_Unbound) {
  70.     error("Must supply the object when making weak pointers.");
  71.     return NULL;
  72.     }
  73.     else
  74.     return make_weak_pointer(object);
  75. }
  76.  
  77. void dylan_weak_pointer_object(obj_t meth, struct thread *thread, obj_t *args)
  78. {
  79.     obj_t weak = args[0];
  80.     obj_t *old_sp = args-1;
  81.  
  82.     old_sp[0] = WEAK(weak)->object;
  83.     old_sp[1] = WEAK(weak)->broken ? obj_True : obj_False;
  84.  
  85.     thread->sp = old_sp + 2;
  86.  
  87.     do_return(thread, old_sp, old_sp);
  88. }
  89.  
  90.  
  91.  
  92. /* GC routines. */
  93.  
  94. static int scav_weak_pointer(struct object *obj)
  95. {
  96.     struct weak_pointer *weakptr = (struct weak_pointer *)obj;
  97.  
  98.     if (!weakptr->broken && obj_is_ptr(weakptr->object)) {
  99.     weakptr->next = WeakPointers;
  100.     WeakPointers = weakptr;
  101.     }
  102.  
  103.     return sizeof(struct weak_pointer);
  104. }
  105.  
  106. static obj_t trans_weak_pointer(obj_t weakptr)
  107. {
  108.     return transport(weakptr, sizeof(struct weak_pointer));
  109. }
  110.  
  111. void scavenge_weak_roots(void)
  112. {
  113.     scavenge(&obj_WeakPointerClass);
  114.     WeakPointers = NULL;
  115. }
  116.  
  117. void break_weak_pointers(void)
  118. {
  119.     struct weak_pointer *w, *n;
  120.  
  121.     for (w = WeakPointers; w != NULL; w = n) {
  122.     if (obj_ptr(struct object *, w->object)->class == ForwardingMarker)
  123.         scavenge(&w->object);
  124.     else {
  125.         w->object = obj_False;
  126.         w->broken = TRUE;
  127.     }
  128.     n = w->next;
  129.     w->next = NULL;
  130.     }
  131. }
  132.  
  133.  
  134. /* Init stuff. */
  135.  
  136. void make_weak_classes(void)
  137. {
  138.     obj_WeakPointerClass
  139.     = make_builtin_class(scav_weak_pointer, trans_weak_pointer);
  140. }
  141.  
  142. void init_weak_classes(void)
  143. {
  144.     init_builtin_class(obj_WeakPointerClass, "<weak-pointer>", obj_ObjectClass,
  145.                NULL);
  146. }
  147.  
  148. void init_weak_functions(void)
  149. {
  150.     define_method("make", list1(singleton(obj_WeakPointerClass)), FALSE,
  151.           list1(pair(symbol("object"), obj_Unbound)),
  152.           FALSE, obj_WeakPointerClass, dylan_make_weak_pointer);
  153.     define_generic_function("weak-pointer-object", 1, FALSE, obj_False, FALSE,
  154.                 list2(obj_ObjectClass, obj_BooleanClass),
  155.                 obj_False);
  156.     add_method(find_variable(module_BuiltinStuff,symbol("weak-pointer-object"),
  157.                  FALSE, FALSE)->value,
  158.            make_raw_method("weak-pointer-object",
  159.                    list1(obj_WeakPointerClass), FALSE, obj_False,
  160.                    FALSE, list2(obj_ObjectClass, obj_BooleanClass),
  161.                    obj_False, dylan_weak_pointer_object));
  162. }
  163.